/**
 * Controller
 *
 */

#include "include/controller.h"
#include <iostream.h>
#include <QStringList>
#include <QVariant>

Controller::Controller()
{
	model=NULL;
	
}

/**
 * Initieer de core.
 */
void Controller::init()
{
	model=new Model();
	systray=new Systray();
	rulesWindow=new RulesWindow();	
	addRuleDialog=new AddRuleDialog();
	settingsDialog=new SettingsDialog();
 	//Test code
/**
	Value rule=Value(objectValue);
	rule["rate"]="100";
	rule["limit"]="200";
	rule["direction"]="incoming";
	rule["priority"]="1";
	//rule["filters"]["0"]["u32"]["src_ip"]["value_0"]="127.0.0.1";
	//rule["filters"]["0"]["u32"]["protocols"]["tcp"]["tcp_control_bits"]["enum_0"]="ack";
	
	rule["filters"][1][1]["path"]=".u32";
	rule["filters"][1][1]["value"][3]="1";
	rule["filters"][1][2]["path"]=".u32.1dst_ip";
	rule["filters"][1][2]["value"][1]="192.1.123.0/32";
	rule["filters"][1][3]["path"]=".u32.protocols.tcp";
	rule["filters"][1][4]["path"]=".u32.protocols.tcp.src_port";
	rule["filters"][1][4]["value"][1]="884";
	rule["filters"][1][5]["path"]=".u32.protocols.tcp.dst_port";
	rule["filters"][1][5]["value"][1]="87";
	//rule["filters"][1][6]["path"]=".u32.protocols.tcp.tcp_control_bits";
	rule["filters"][1][6]["path"]=".u32.protocols.tcp.tcp_control_bits.ack";
	//rule["filters"][1][6]["enumv"][1]="ack";

	rule["filters"][2][1]["path"]=".u32";
	rule["filters"][2][1]["value"][3]="1";
	rule["filters"][2][2]["path"]=".u32.0src_ip";
	rule["filters"][2][2]["value"][1]="123.123.123.21/32";
	rule["filters"][2][3]["path"]=".u32.1dst_ip";
	rule["filters"][2][3]["value"][1]="192.1.123.0/32";
*/	

	model->init();

	//Make connections
	connect(systray,SIGNAL(newAction(QString)),this,SLOT(handleSystrayAction(QString)));
	connect(addRuleDialog,SIGNAL(saveRule(Value,int)),this,SLOT(retrieveSaveRule(Value,int)));
	connect(rulesWindow,SIGNAL(wantRates()),this,SLOT(giveRates()));
	connect(rulesWindow,SIGNAL(deleteRule(int)),this,SLOT(retrieveDeleteRule(int)));
	connect(rulesWindow,SIGNAL(editRule(int)),this,SLOT(retrieveEditRule(int)));
	connect(rulesWindow,SIGNAL(addRule()),this,SLOT(retrieveAddRule()));
	connect(addRuleDialog,SIGNAL(rejectme()),this,SLOT(rejectRuleDialog()));
	connect(rulesWindow,SIGNAL(showSettings()),this,SLOT(showSettings()));
	connect(settingsDialog,SIGNAL(newSettings(Value)),this,SLOT(retrieveNewSettings(Value)));

	createSystrayActions();

	rulesWindow->show();
	rulesWindow->init(model->getSettings());
	rulesWindow->fillTable(model->getRules());
}

void Controller::createSystrayActions()
{
        systray->addMenuAction("add rule");
        systray->addMenuAction("settings");
        systray->addMenuAction("");
        systray->addMenuAction("quit");
}
void Controller::retrieveDeleteRule(int ruleID)
{
	if(ruleID==-1)
		return;
	model->delRule(ruleID);
	rulesWindow->fillTable(model->getRules());
}
//Start addruledialog in edit mode
void Controller::retrieveEditRule(int ruleID)
{
	addRuleDialog->fillForm(model->getRules()[QString().setNum(ruleID).toStdString()],ruleID);
        addRuleDialog->show();
	QApplication::setActiveWindow(addRuleDialog);
}
//Start addruledialog in new mode
void Controller::retrieveAddRule()
{
	addRuleDialog->fillForm(Value(nullValue),0);
        addRuleDialog->show();
}
void Controller::retrieveSaveRule(Value rule,int ruleID)
{
	if(ruleID)
		model->editRule(rule,ruleID);
	else
		model->addRule(rule);
	rulesWindow->fillTable(model->getRules());
	rejectRuleDialog();	
}
void Controller::rejectRuleDialog()
{
	addRuleDialog->hide();
}
void Controller::giveRates()
{
	rulesWindow->fillRates(model->getRates());
}
void Controller::retrieveNewSettings(Value newSettings)
{
	model->writeSettings(newSettings);
}

void Controller::showSettings()
{
	settingsDialog->fillForm(model->getSettings());
	settingsDialog->show();
}
void Controller::handleSystrayAction(QString action)
{
        //Handelt de actie van zooi af.
        if(action=="add rule") {
                retrieveAddRule();
                return;
        }
        //Handelt de actie van settings af.
        if(action=="settings") {
		showSettings();
                return;
        }
        //Handelt de actie van quit af.
        if(action=="quit") {
                model->stop();
                qApp->quit();
                return;
        }
        //Left mouse click or left mouse double click
        if(action=="3" || action=="2") {
                if(rulesWindow->isVisible())
                        rulesWindow->close();
                else {
                        rulesWindow->show();
                }
                return;
        }
}
